package org.example.service;

import org.example.exception.BizException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class UploadService {
    private final String uploadPath;
    private final FileStorage fileStorage;
    private final Map<String, Lock> taskLock;
    private final Map<String, Integer> activeTaskCountMap;
    private final Logger logger;
    public UploadService(String uploadPath,FileStorage fileStorage){
        this.uploadPath=uploadPath;
        this.fileStorage=fileStorage;
        this.taskLock=new ConcurrentHashMap<>();
        this.activeTaskCountMap=new ConcurrentHashMap<>();
        this.logger= LoggerFactory.getLogger(UploadService.class);
    }
    private void saveChunk(String target,InputStream inputStream){

    }
    private void increaseTaskCount(String key,int count){
        synchronized (activeTaskCountMap){
            int activeCount=activeTaskCountMap.computeIfAbsent(key,v->0);
            activeCount+=count;
            activeTaskCountMap.put(key,activeCount);
        }
    }
    public void uploadChunk(String uploadId,int chunkIndex,InputStream inputStream){
        String mergeTaskKey=uploadId+":merge";
        Lock mergeTaskLock=taskLock.get(mergeTaskKey);
        if (mergeTaskLock!=null){
            logger.error("上传分片{}失败，上传任务{}正在合并",chunkIndex,uploadId);
            throw new BizException(String.format("上传分片%d失败，上传任务%s正在合并",chunkIndex,uploadId),null);
        }
        String chunkKey=uploadId+":"+chunkIndex;
        Lock lock = taskLock.computeIfAbsent(chunkKey, k -> new ReentrantLock());
        if (lock.tryLock()){
            String activeTaskKey=null;
            try {
                activeTaskKey=uploadId+":upload";
                increaseTaskCount(activeTaskKey,1);
                Path chunkPath = Paths.get(uploadPath, uploadId, String.valueOf(chunkIndex));
                saveChunk(chunkPath.toString(), inputStream);
            }catch (Exception e){
                logger.error("上传任务{}的分片{}上传失败，原因{}",uploadId,chunkIndex,e.getMessage());
                throw new BizException("上传失败",e);
            }finally {
                increaseTaskCount(activeTaskKey,-1);
                lock.unlock();
            }
        }else{
            logger.error("上传任务{}的分片{}已在上传中",uploadId,chunkIndex);
            throw new BizException(String.format("上传任务%s的分片%d已在上传中",uploadId,chunkIndex),null);
        }
    }
    public void merge(String uploadId){
        String mergeKey=uploadId+":merge";
        Lock mergeTaskKey=taskLock.get(mergeKey);
        if (mergeTaskKey!=null){

        }
    }
}
